﻿using AspNetCoreRateLimit;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace MyFurion.Start
{
    /// <summary>
    /// 
    /// </summary>
    public class Startup:AppStartup
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="services"></param>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddJwt<JwtHandler>(enableGlobalAuthorize: true);//启用Jwt 身份验证 全局权限
            services.AddSensitiveDetection();//注册脱敏词汇检测服务
            services.AddControllers().AddNewtonsoftJson();//防止json数据类型转换失败
            services.AddControllers().AddInjectWithUnifyResult<XnRestfulResultProvider>();//规范化输出设置
            services.AddCorsAccessor();//配置跨域                 
            //统一日期类型返回
            services.AddControllersWithViews().AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                options.SerializerSettings.Converters.AddLongTypeConverters();
            });
            // 注册EventBus服务
            services.AddEventBus(builder =>
            {
                // 注册 Log 日志订阅者
                builder.AddSubscriber<LogEventSubscriber>();
            });
            //注册全局请求日志
            services.Configure<MvcOptions>(options =>
            {
                options.Filters.Add<RequestLogFilter>();
            });
            services.Configure<KestrelServerOptions>(options =>
            {
                options.Limits.MaxRequestBodySize = int.MaxValue;
            });
            services.AddIPRate();//ip请求频率限制
            //本地日志文件配置
            Array.ForEach(new[] { LogLevel.Information, LogLevel.Error }, logLevel =>
            {
                services.AddFileLogging("Logs/{1}-{0:yyyy}-{0:MM}-{0:dd}-{0:HH}.log", options =>
                {
                    options.FileNameRule = fileName => string.Format(fileName, DateTime.UtcNow, logLevel.ToString());
                    options.WriteFilter = logMsg => logMsg.LogLevel == logLevel;
                    options.Append = true;
                    //options.MessageFormat = (logMsg) =>
                    //{
                    //    var stringBuilder = new System.Text.StringBuilder();
                    //    stringBuilder.Append(System.DateTime.Now.ToString("o"));
                    //    // 其他的。。。自己组装
                    //    return stringBuilder.ToString();
                    //};
                });
            });
            //数据库存储日志 （使用数据库存储日志，可将本地文件存储日志配置代码注释，否则磁盘日志文件和数据库日志都会存在）
            //services.AddDatabaseLogging<DatabaseLoggingWriter>(options => { });
            //数据库IOC注册
            SqlSugarSetup.AddSqlsugarSetup();
            //redis连接配置
            services.AddStackExchangeRedisCache(options =>
            {
                options.Configuration = App.GetConfig<string>("RedisSettings:RedisConnection");//连接字符串              
                options.InstanceName = App.GetConfig<string>("RedisSettings:PreFix");//键名前缀
            });
            /*
             定时任务—清除本地磁盘日志文件
             如果IIS部署的情况下，那么需要设置 IIS 禁止回收：
             1）应用池—右击—高级设置—常规—启动模式—选择AlwaysRunning
             2）应用池—右击—高级设置—进程模型—闲置超时（分钟）的值修改为0
             */
            services.AddSchedule(options =>
            {
                options.AddJob<LogJob>(Furion.Schedule.Triggers.WeeklyAt("SUN"));//每周星期天零点进行 SUN（星期天），MON，TUE，WED，THU，FRI，SAT
                //options.AddJob<LogJob>(Furion.Schedule.Triggers.PeriodMinutes(1));//每5分钟执行一次
            });
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="env"></param>
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            //  NGINX 反向代理获取真实IP
            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });
            app.UseUnifyResultStatusCodes();// 添加状态码拦截中间件 添加规范化结果状态码        
            app.UseHttpsRedirection();// 强制https
            app.UseStaticFiles(); //启用静态文件
            app.UseRouting();
            app.UseCorsAccessor();//跨域中间件
            //开启身份认证
            app.UseAuthentication();
            app.UseAuthorization();
            //启用swagger
            app.UseInject();
            //启用客户端IP限制速率
            app.UseIpRateLimiting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}
